﻿package
{
	import caurina.transitions.Tweener;
	
	import flash.display.MovieClip;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import mx.flash.UIMovieClip;

	public class Clock extends UIMovieClip
	{
		private var timer:Timer;
		private var date:Date;
		
		public var second_nd:MovieClip;
		public var minute_nd:MovieClip;
		public var hour_nd:MovieClip;
		
		public function Clock()
		{
			super();
			//setup timer to retrieve new system datetime and rotate the needles
			timer=new Timer(1000);
			timer.addEventListener(TimerEvent.TIMER,onTimer);
			
			//position the needles before timer start;
			date=new Date();
			setNeedleRotation();
			
			timer.start();
		}
		
		/**
		 * get actual new angle between -180 and 180 according original rotation;
		 * because flash runtime set angle degree that larger than 360 to 360 sub
		 * 
		 * @param oldAngle a number of original angle between (-180,180)
		 * @param newAngle a number of destination angle could be any degree value;
		 * 
		 * @return a number between -180 and 180 according original rotation;
		 * */
		private function getActualNewAngle(oldAngle:Number,newAngle:Number):Number
		{
			newAngle=newAngle%360;
			var distanceNormal:Number = Math.abs(oldAngle - newAngle);
			var distanceForward:Number = Math.abs(oldAngle - (newAngle + 360));
			var distanceBackward:Number = Math.abs(oldAngle - (newAngle - 360));
			var actualNewAngle:Number;
			if (Math.min(distanceNormal, Math.min(distanceForward, 
			distanceBackward)) == distanceForward) {
				actualNewAngle = newAngle + 360;
			} else if (Math.min(distanceNormal, Math.min(distanceForward, 
			distanceBackward)) == distanceBackward) {
				actualNewAngle = newAngle - 360;
			} else {
				actualNewAngle = newAngle;
			}
			return actualNewAngle%360;
		}
		
		private function setNeedleRotation():void
		{
			var second_ng:Number=date.getSeconds()*6;
			Tweener.addTween(second_nd,{rotation:getActualNewAngle(second_nd.rotation,second_ng),time:0.5,transition:"easeOutElastic"});
			
			if(timer.currentCount%10==0)
			{
				var minute_ng:Number=date.getMinutes()*6+date.getSeconds()/60*6;
				Tweener.addTween(minute_nd,{rotation:getActualNewAngle(minute_nd.rotation,minute_ng),time:0.5,transition:"easeOutQuad"});
			}
			
			if(timer.currentCount%60==0)
			{
				var hour_ng:Number=date.getHours()*30+date.getMinutes()/60*30;
				Tweener.addTween(hour_nd,{rotation:getActualNewAngle(hour_nd.rotation,hour_ng),time:0.5,transition:"easeOutQuad"});
			}
		}
		
		private function onTimer(event:TimerEvent):void
		{
			date=new Date();
			
			setNeedleRotation();
		}
		
	}
}